﻿using System.Collections.Generic;
using HCore.Core;
using HCore.IOC.Beans.Factory.Attribute.Attr;
using HCore.Unity.Behaviour;
using HCore.Unity.Core;
using HCore.Unity.Manager;
using TMPro;
using UnityEngine;

namespace HCore.Tests.Runtime.Minesweeper.Scripts
{
    public class GridPrefabVisual : HCoreMonoBehaviour
    {
        // [SerializeField] private Transform pfGridPrefabVisualNode;
        [SerializeField] private Sprite FlagSprite;
        [SerializeField] private Sprite MineSprite;
        private Grid2D<MapGridObject> mGrid;

        /// <summary>
        ///     显示全部地图
        /// </summary>
        private bool mIsRevealEntireMap;

        [Autowired] private PrefabManager mPrefabManager;
        private bool mUpdateVisual;
        private Transform[,] mVisualNodeArray;
        private List<Transform> mVisualNodeList;

        protected override void Awake()
        {
            base.Awake();
            mVisualNodeList = new List<Transform>();
        }

        private void Update()
        {
            if (mUpdateVisual)
            {
                mUpdateVisual = false;
                UpdateVisual();
            }
        }

        /// <summary>
        ///     设置 全部显示格子
        /// </summary>
        /// <param name="isRevealEntireMap"></param>
        public void SetRevealEntireMap(bool isRevealEntireMap)
        {
            mIsRevealEntireMap = isRevealEntireMap;
            UpdateVisual();
        }

        public void Setup(Grid2D<MapGridObject> grid)
        {
            mGrid = grid;
            mVisualNodeArray = new Transform[grid.Width, grid.Height];

            ForUtils.For(grid.Width, grid.Height, (x, y) =>
            {
                var gridPosition = new Vector3(x, y) * grid.CellSize + Vector3.one * (grid.CellSize * .5f);
                var visualNode = CreateVisualNode(gridPosition);
                mVisualNodeArray[x, y] = visualNode;
                mVisualNodeList.Add(visualNode);
            });

            HideNodeVisuals();

            UpdateVisual();

            grid.AddCellChangedListener(_ => UpdateVisual());
        }

        public void UpdateVisual()
        {
            HideNodeVisuals();

            ForUtils.For(mGrid.Width, mGrid.Height, (x, y) =>
            {
                var gridObject = mGrid.GetCell(x, y);
                var visualNode = mVisualNodeArray[x, y];
                visualNode.gameObject.SetActive(true);
                SetupVisualNode(visualNode, gridObject);
            });
        }

        private void HideNodeVisuals()
        {
            foreach (var visualNodeTransform in mVisualNodeList) visualNodeTransform.gameObject.SetActive(false);
        }

        private Transform CreateVisualNode(Vector3 position)
        {
            var prefabObject = mPrefabManager.LoadPrefabGameObject("Prefabs/PFMinesweeperGridNodeVisual", position, Quaternion.identity);
            return prefabObject.transform;
        }

        private void SetupVisualNode(Transform visualNodeTransform, MapGridObject gridObject)
        {
            // 雷
            var iconSpriteRenderer = visualNodeTransform.Find("IconSprite").GetComponent<SpriteRenderer>();
            // 数字
            var indicatorText = visualNodeTransform.Find("MineIndicatorText").GetComponent<TextMeshPro>();
            // 蒙版
            var hiddenTransform = visualNodeTransform.Find("HiddenSprite");

            // 格子被翻开了。
            if (gridObject.Revealed || mIsRevealEntireMap)
            {
                hiddenTransform.gameObject.SetActive(false);
                switch (gridObject.GridType)
                {
                    // 撒也没有
                    default:
                    case GridType.Empty:
                        iconSpriteRenderer.gameObject.SetActive(false);
                        indicatorText.gameObject.SetActive(false);
                        break;
                    // 地雷
                    case GridType.Mine:
                        iconSpriteRenderer.sprite = MineSprite;
                        iconSpriteRenderer.gameObject.SetActive(true);
                        indicatorText.gameObject.SetActive(false);
                        break;
                    case GridType.MineNum1:
                    case GridType.MineNum2:
                    case GridType.MineNum3:
                    case GridType.MineNum4:
                    case GridType.MineNum5:
                    case GridType.MineNum6:
                    case GridType.MineNum7:
                    case GridType.MineNum8:
                        iconSpriteRenderer.gameObject.SetActive(false);
                        indicatorText.gameObject.SetActive(true);
                        switch (gridObject.GridType)
                        {
                            case GridType.MineNum1:
                                indicatorText.text = "1";
                                break;
                            case GridType.MineNum2:
                                indicatorText.text = "2";
                                break;
                            case GridType.MineNum3:
                                indicatorText.text = "3";
                                break;
                            case GridType.MineNum4:
                                indicatorText.text = "4";
                                break;
                            case GridType.MineNum5:
                                indicatorText.text = "5";
                                break;
                            case GridType.MineNum6:
                                indicatorText.text = "6";
                                break;
                            case GridType.MineNum7:
                                indicatorText.text = "7";
                                break;
                            case GridType.MineNum8:
                                indicatorText.text = "8";
                                break;
                        }

                        break;
                }
            }
            // 如果没有翻开格子
            else
            {
                indicatorText.gameObject.SetActive(false);
                hiddenTransform.gameObject.SetActive(true);

                // 有旗帜
                if (gridObject.Flagged())
                {
                    iconSpriteRenderer.sprite = FlagSprite;
                    iconSpriteRenderer.gameObject.SetActive(true);
                }
                // 无旗帜
                else
                {
                    iconSpriteRenderer.gameObject.SetActive(false);
                }
            }
        }

        /*
         * Represents a single Grid Object
         * */
        public class GridPrefabVisualObject
        {
            private readonly Grid2D<GridPrefabVisualObject> mGrid;
            private readonly int mX;
            private readonly int mY;
            private int mValue;

            public GridPrefabVisualObject(Grid2D<GridPrefabVisualObject> grid, int x, int y)
            {
                mGrid = grid;
                mX = x;
                mY = y;
            }

            public void SetValue(int value)
            {
                mValue = value;
                mGrid.TriggerCellChanged(mX, mY);
            }

            public override string ToString()
            {
                return $"{mX}, {mY}\n{mValue}";
            }
        }
    }
}